package com.demo.sso.sdk.interceptor;

import com.demo.sso.sdk.config.SsoSdkProperties;
import com.demo.sso.sdk.service.SsoClientService;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;

import java.io.IOException;

/**
 * SSO登录拦截器
 * 拦截需要登录的请求，如果用户未登录则重定向到SSO登录页面
 *
 * @author SpringCloud团队
 * @version 1.0.0
 * @since 2025-01-01
 */
public class SsoLoginInterceptor implements HandlerInterceptor {

    private static final Logger logger = LoggerFactory.getLogger(SsoLoginInterceptor.class);

    private final SsoClientService ssoClientService;
    private final SsoSdkProperties properties;

    public SsoLoginInterceptor(SsoClientService ssoClientService, SsoSdkProperties properties) {
        this.ssoClientService = ssoClientService;
        this.properties = properties;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 如果SSO未启用，直接通过
        if (!properties.getEnabled()) {
            return true;
        }

        String requestUri = request.getRequestURI();
        logger.debug("SSO intercepting request: {}", requestUri);

        // 排除登录、登出、回调等路径
        if (isExcludedPath(requestUri)) {
            logger.debug("Request path is excluded: {}", requestUri);
            return true;
        }

        // 检查用户是否已登录
        if (ssoClientService.isLoggedIn(request)) {
            logger.debug("User is logged in, allowing request: {}", requestUri);
            return true;
        }

        // 用户未登录，重定向到SSO登录页面
        logger.info("User not logged in, redirecting to SSO login page. Request URI: {}", requestUri);
        redirectToLogin(request, response);
        return false;
    }

    /**
     * 判断是否为排除路径
     *
     * @param requestUri 请求URI
     * @return true-排除，false-不排除
     */
    private boolean isExcludedPath(String requestUri) {
        // 登录路径
        if (requestUri.equals(properties.getLoginPath()) || requestUri.startsWith(properties.getLoginPath() + "/")) {
            return true;
        }

        // 登出路径
        if (requestUri.equals(properties.getLogoutPath()) || requestUri.startsWith(properties.getLogoutPath() + "/")) {
            return true;
        }

        // 回调路径
        if (requestUri.equals(properties.getCallbackPath()) || requestUri.startsWith(properties.getCallbackPath() + "/")) {
            return true;
        }

        // 静态资源路径
        if (requestUri.startsWith("/static/") ||
                requestUri.startsWith("/css/") ||
                requestUri.startsWith("/js/") ||
                requestUri.startsWith("/images/") ||
                requestUri.startsWith("/img/") ||
                requestUri.startsWith("/favicon.ico")) {
            return true;
        }

        // API路径（如果有特殊需求）
        if (requestUri.startsWith("/api/public/")) {
            return true;
        }

        return false;
    }

    /**
     * 重定向到SSO登录页面
     *
     * @param request  HTTP请求
     * @param response HTTP响应
     * @throws IOException IO异常
     */
    private void redirectToLogin(HttpServletRequest request, HttpServletResponse response) throws IOException {
        try {
            String loginUrl = ssoClientService.generateLoginUrl(request);
            response.sendRedirect(loginUrl);
        } catch (Exception e) {
            logger.error("Failed to generate SSO login URL", e);
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "SSO service unavailable");
        }
    }
}